﻿using Learun.Util;
using Learun.Util.SqlSugar;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using DbType = System.Data.DbType;

namespace Learun.Application.TwoDevelopment.ZZDT_EC
{
    /// <summary>
    /// 版 本 PIT-ADMS V7.0.3 敏捷开发框架
    /// Copyright (c) 2013-2018 Hexagon PPM
    /// 创 建：超级管理员
    /// 日 期：2022-06-21 15:33
    /// 描 述：工程数据关联表
    /// </summary>
    public class ec_enginedata_relService
    {
        #region 仓储
        Repository<ec_projectEntity> _projectRepository => new Repository<ec_projectEntity>();
        Repository<ec_enginedata_relEntity> _enginedataRelRepository => new Repository<ec_enginedata_relEntity>();
        Repository<ec_enginedata_pixelEntity> _enginedataPixelRepository => new Repository<ec_enginedata_pixelEntity>();
        Repository<ec_enginedataEntity> _enginedataRepository => new Repository<ec_enginedataEntity>();
        Repository<ec_CircuitBreakerEntity> _circuitBreakerRepository => new Repository<ec_CircuitBreakerEntity>();
        #endregion
        #region 获取数据
        List<string> enginedataIDs = new List<string>();
        /// <summary>
        /// 获取列表分页数据
        /// <param name="pagination">分页参数</param>
        /// <summary>
        /// <returns></returns>
        public IEnumerable<CableWayRes> GetCableWay(string ProjectId, List<CableConnRel> CablePixelIDs)
        {
            try
            {
                var ProjectEntity = new ec_projectEntity();
                var pixelTableName = ProjectSugar.TableName<ec_enginedata_pixelEntity>(ProjectId);

                var engineIDs = new List<string>();
                //参考写法
                CablePixelIDs.ForEach(x =>
                {
                    engineIDs.AddRange(_enginedataPixelRepository.AsQueryable().AS(pixelTableName)
                        .Where(y => y.DrawingFileID == x.DrawingID && y.PixelCode == x.CablePixelID)
                        .Select(y => y.EngineDataID).ToList());
                });
                engineIDs = engineIDs.Distinct().ToList();
                engineIDs.ForEach(x =>
                {
                    if (!enginedataIDs.Contains(x))
                    {
                        bfs(x, ProjectId);
                    }
                });
                var res = new List<CableWayRes>();
                var engineDataTableName = ProjectSugar.TableName<ec_enginedataEntity>(ProjectId);
                var objectTypeTableName = ProjectSugar.TableName<ec_objecttypeEntity>(ProjectId);
                var circuitBreakerTableName = ProjectSugar.TableName<ec_CircuitBreakerEntity>(ProjectId);
                res.AddRange(_enginedataRepository.AsQueryable().AS(engineDataTableName)
                    .InnerJoin<ec_objecttypeEntity>((a, b) => a.ObjectTypeID == b.ObjectTypeID).AS<ec_objecttypeEntity>(objectTypeTableName)
                    .Where((a, b) => enginedataIDs.Contains(a.EngineDataID))
                    .Select((a, b) => new CableWayRes()
                    {
                        EngineDataID = a.EngineDataID,
                        TagNumber = a.TagNumber,
                        ObjectTypeName = b.ObjectTypeName
                    }).ToList());
                res.AddRange(_circuitBreakerRepository.AsQueryable().AS(circuitBreakerTableName)
                    .Where(x => enginedataIDs.Contains(x.EngineerDataID))
                    .Select(x => new CableWayRes()
                    {
                        EngineDataID = x.EngineerDataID,
                        TagNumber = x.Name,
                        ObjectTypeName = x.CB_Type
                    }).ToList());
                return res;
            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }

        #endregion

        #region 提交数据

        /// <summary>
        /// 删除实体数据
        /// <param name="keyValue">主键</param>
        /// <summary>
        /// <returns></returns>
        public void DeleteEntity(string ProjectId, string keyValue)
        {
            try
            {
                if (!string.IsNullOrEmpty(ProjectId))
                {
                    var ProjectEntity = _projectRepository.GetById(ProjectId);
                    if (ProjectEntity != null)
                    {

                        SqlSugarHelper.Db.Ado.ExecuteCommand($" DELETE FROM ec_enginedata_rel_{ProjectEntity.ProjectIndex} WHERE EngineDataRelID IN ('{keyValue}');");


                    }
                    else
                    {
                        throw new Exception("ProjectId无效");
                    }
                }
                else
                {
                    _enginedataRelRepository.Delete(t => t.EngineDataRelID == keyValue);
                }

            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }

        /// <summary>
        /// 删除ec_enginedata_rel
        /// </summary>
        /// <param name="ProjectId"></param>
        /// <param name="RelTypeId"></param>
        /// <param name="ID1">如果ID1为空，就删除所有2端为ID2的</param>
        /// <param name="ID2">如果ID2为空，就删除所有1端为ID1的</param>
        public void DeleteEntity(string ProjectId, string RelTypeId, string ID1, string ID2)
        {
            try
            {
                if (!string.IsNullOrEmpty(ProjectId))
                {
                    var ProjectEntity = _projectRepository.GetById(ProjectId);
                    if (ProjectEntity != null)
                    {
                        if (ID1 == "" && ID2 != "")
                        {
                            SqlSugarHelper.Db.Ado.ExecuteCommand($" DELETE FROM ec_enginedata_rel_{ProjectEntity.ProjectIndex} WHERE RelTypeId ='{RelTypeId}' AND RelEngineData2ID='{ID2}';");

                        }
                        else if (ID1 != "" && ID2 == "")
                        {
                            SqlSugarHelper.Db.Ado.ExecuteCommand($" DELETE FROM ec_enginedata_rel_{ProjectEntity.ProjectIndex} WHERE RelTypeId ='{RelTypeId}' AND RelEngineData1ID='{ID1}';");

                        }
                        else
                        {
                            SqlSugarHelper.Db.Ado.ExecuteCommand($" DELETE FROM ec_enginedata_rel_{ProjectEntity.ProjectIndex} WHERE RelTypeId ='{RelTypeId}' AND RelEngineData1ID='{ID1}' AND RelEngineData2ID='{ID2}';");


                        }

                    }
                    else
                    {
                        throw new Exception("ProjectId无效");
                    }
                }
                else
                {
                }

            }
            catch (Exception ex)
            {
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }
        /// <summary>
        /// 保存实体数据（新增、修改）
        /// </summary>
        /// <param name="ProjectId"></param>
        /// <param name="engineDataRelAdd">要增加的rel关系的记录</param>
        /// <param name="delEngineDataRelIDs">待移除的rel关系的记录</param>
        public void SaveEntity(string ProjectId, List<ec_enginedata_relEntity> engineDataRelAdd, List<string> delEngineDataRelIDs)
        {
            SqlSugarHelper.Db.BeginTran();
            try
            {

                if (!string.IsNullOrEmpty(ProjectId))
                {
                    var ProjectEntity = _projectRepository.GetById(ProjectId);
                    string strWhere = string.Join(",", (from tb in delEngineDataRelIDs select "'" + tb + "'").ToList());
                    if (!string.IsNullOrEmpty(strWhere))
                    {
                        SqlSugarHelper.Db.Ado.ExecuteCommand($" DELETE FROM ec_enginedata_rel_{ProjectEntity.ProjectIndex} WHERE EngineDataRelID IN ({strWhere});");
                    }
                    //db.InsertByNoMap(engineDataRelAdd, $"ec_enginedata_rel_{ProjectEntity.ProjectIndex}");
                    _enginedataRelRepository.AsInsertable(engineDataRelAdd).AS($"ec_enginedata_rel_{ProjectEntity.ProjectIndex}").ExecuteCommand();
                }
                else
                {
                    _enginedataRelRepository.Delete(t => delEngineDataRelIDs.Contains(t.EngineDataRelID));
                    _enginedataRelRepository.InsertRange(engineDataRelAdd);
                }
                SqlSugarHelper.Db.CommitTran();
            }
            catch (Exception ex)
            {
                SqlSugarHelper.Db.RollbackTran();
                if (ex is ExceptionEx)
                {
                    throw;
                }
                else
                {
                    throw ExceptionEx.ThrowServiceException(ex);
                }
            }
        }

        #endregion
        LinkedList<ec_enginedata_relEntity> rels = new LinkedList<ec_enginedata_relEntity>();
        /// <summary>
        /// 通过邻接节点来获取下一个节点
        /// </summary>
        /// <returns></returns>
        public ec_enginedata_relEntity getNextNeighbor(string engineDataID)
        {
            return rels.FirstOrDefault(x => (x.RelEngineData1ID == engineDataID || x.RelEngineData2ID == engineDataID)
                && !x.IsVisited);
        }

        //对一个结点进行广度优先遍历的方法
        public void bfs(string engineDataID, string ProjectId)
        {
            //把整张表取到内存提高性能
            var tableName = ProjectSugar.TableName<ec_enginedata_relEntity>(ProjectId);
            var enginedataRels = _enginedataRelRepository.AsQueryable().AS(tableName)
                    .ToList();
            enginedataRels.ForEach(x =>
            {
                x.EngineDataID = x.RelEngineData1ID == engineDataID ? x.RelEngineData2ID : x.RelEngineData1ID;
                rels.AddLast(x);
            });

            //这里可以访问第一个点的
            //{ 
            //}

            LinkedList<string> queue = new LinkedList<string>();
            queue.AddLast(engineDataID);
            string u;
            while (queue.Count != 0)
            {
                u = queue.First.Value;
                if (!enginedataIDs.Contains(u))
                {
                    enginedataIDs.Add(u);
                }
                queue.RemoveFirst();
                ec_enginedata_relEntity w = rels.First();
                while (w != null)
                {
                    if (!w.IsVisited)
                    {
                        //这里每个节点进来一次
                        //{ 
                        //}
                        w.IsVisited = true;
                        queue.AddLast(w.EngineDataID);
                    }
                    w = getNextNeighbor(u);
                }
            }
        }
    }
}
